package com.xmb.wcapi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmb.wcapi.constant.ConfigConstant;
import com.xmb.wcapi.constant.DepConstant;
import com.xmb.wcapi.entity.*;
import com.xmb.wcapi.mapper.QualityDataMapper;
import com.xmb.wcapi.mapper.SysConfigMapper;
import com.xmb.wcapi.service.IBaseMaterialService;
import com.xmb.wcapi.service.ICustomQualityDataService;
import com.xmb.wcapi.service.IInitialStockService;
import com.xmb.wcapi.service.IQualityDataService;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class QualityDataServiceImpl extends ServiceImpl<QualityDataMapper, QualityData> implements IQualityDataService {

    @Resource
    private QualityDataMapper dataMapper;

    @Resource
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private IBaseMaterialService baseMaterialService;

    @Resource
    private ICustomQualityDataService customQualityDataService;

    @Resource
    private IInitialStockService initialStockService;

    @Override
    public IPage<QualityData> qualityData(Integer page, Integer limit, String cusCode, String startTime, String endTime, String material) {
        IPage<QualityData> data = getData(page, limit, cusCode, startTime, endTime,material);
        return data;
    }

    @Override
    public IPage<QualityData> selectPageList(Integer page, Integer limit,String startTime, String endTime,List<String> set){
        return dataMapper.selectPageList(new Page<>(page, limit), startTime, endTime, set);
    }

    public List<JSONObject> getMaterialDaySum(boolean one, String time, Set<String> material){
        return dataMapper.getMaterialDaySum(one, time, material);
    }

    public IPage<QualityData> getData(Integer page, Integer limit, String cusCode, String startTime, String endTime, String material){
        //获取供应商
        List<String> set = new ArrayList<>();
        //获取本地设定的料号
        List<BaseMaterial> materials = baseMaterialService.list(Wrappers.lambdaQuery(BaseMaterial.class)
                .eq(BaseMaterial::getCusCode, cusCode).eq(BaseMaterial::isChecked,true)
                .like(StringUtils.isNotEmpty(material),BaseMaterial::getDjMaterial,material)
        );
        if (null != materials){
            set.addAll(materials.stream().map(BaseMaterial::getDjMaterial).collect(Collectors.toList()));
        }
        IPage<QualityData> list = selectPageList(page, limit, startTime, endTime, set);
        if (!list.getRecords().isEmpty()){
            Map<String, List<BaseMaterial>> listMap = materials.stream().collect(Collectors.groupingBy(BaseMaterial::getDjMaterial));
            for (QualityData record : list.getRecords()) {
                //不是委外数据
                if (StringUtils.isEmpty(record.getTypeName())){
                    //计算待处理
                    BigDecimal invest = record.getInvest();
                    invest = invest.subtract(record.getNonDefective()).subtract(record.getDefectiveProducts());
                    record.setPending(invest);
                    record.setPendingCumulative(invest);
                    if (invest.intValue() < 1){
                        record.setPending(BigDecimal.valueOf(0));
                        record.setPendingCumulative(BigDecimal.valueOf(0));
                    }
                    List<BaseMaterial> materialList = listMap.get(record.getMaterial());
                    if (!materialList.isEmpty()){
                        BaseMaterial baseMaterial = materialList.get(0);
                        if (baseMaterial.getClassType().equals("A")){
                            record.setStrDepartmentName(record.getCusMaterial());
                        }
                    }
                }else {
                    //是委外数据
                    record.setInvest(record.getNonDefective());
                    record.setPlanSum(record.getNonDefective());
                    record.setPending(BigDecimal.valueOf(0));
                    record.setPendingCumulative(BigDecimal.valueOf(0));
                    record.setStrDepartmentName(DepConstant.getMessage(record.getMaterial()));
                }
            }
        }
        return list;
    }

    @Override
    public IPage<QualityData> qualityDataNext(Integer page, Integer limit, String cusCode, String startTime, String endTime, String material) {
        //获取基础数据
        IPage<QualityData> list = getData(page, limit, cusCode, startTime, endTime, material);

        //查询本地流转卡数据
        for (CustomQualityData customQualityData : customQualityDataService.qualityDataList(startTime, endTime)) {
            for (DepConstant value : DepConstant.values()) {
                if (customQualityData.getMaterial().contains(value.getCode())){
                    customQualityData.setStrDepartmentName(value.getMessage());
                }
            }
            QualityData bean = BeanUtil.toBean(customQualityData, QualityData.class);
            list.getRecords().add(bean);
        }

        for (QualityData record : list.getRecords()) {
            if(StringUtils.isNotEmpty(record.getStrDepartmentName())){
                record.setStrDepartmentName(record.getStrDepartmentName().replace("课",""));
            }
        }

        //获取配置中的 良率标准
        List<SysConfig> configs = sysConfigMapper.selectList(Wrappers.lambdaQuery(SysConfig.class));
        if (!configs.isEmpty()){
            //根据 科目名称 和 类别分组
            Map<String, List<SysConfig>> collect = configs.stream().collect(Collectors.groupingBy(obj-> obj.getDepName()+"-"+obj.getPartsType()));
            for (QualityData record : list.getRecords()) {
                //拼接 key
                String key = null;
                for (ConfigConstant value : ConfigConstant.values()) {
                    if (record.getStrGoodsName().contains(value.getCode())){
                        key = record.getStrDepartmentName() +"-"+ value.getMessage();
                    }
                }
                List<SysConfig> confs = collect.get(key);
                if(null != confs && !confs.isEmpty()){
                    SysConfig sysConfig = confs.get(0);
                    //良率
                    double per = Double.parseDouble(record.getPercentage());
                    //下限
                    double con = Double.parseDouble(sysConfig.getConfValue());
                    //如果小于最低标准 ，降低不良品 提升良率
                    if (per < con){
                        //循环 -1 一直到最低标准
                        int def = record.getDefectiveProducts().intValue();
                        int non = record.getNonDefective().intValue();
                        for (int i = 1; i <= def ; i++) {
                            double i2 = (double) non / (non + (def - i)) * 100;
                            // 大于良率
                            if (i2 >= con){
                                //把不良品数减下去的加到 投入数 上面
                                record.setInvest(record.getInvest().add(BigDecimal.valueOf(i)));
                                record.setDefectiveProducts(new BigDecimal(def - i));
                                record.setPercentage(new BigDecimal(i2).setScale(BigDecimal.ROUND_DOWN,2).toString());
                                break;
                            }
                        }
                    }

                    //上限
                    double conMax = Double.parseDouble(sysConfig.getConfValueMax());
                    if (per > conMax){
                        int def = record.getDefectiveProducts().intValue();
                        int non = record.getNonDefective().intValue();
                        boolean mark = true;
                        while (mark){
                            ++def;
                            //增加不良品降低良品
                            double i2 = (double) non / (non + def) * 100;
                            // 大于良率
                            if (i2 <= conMax){
                                //把不良品数减下去的加到 投入数 上面
                                record.setInvest(record.getInvest().add(BigDecimal.valueOf(def)));
                                record.setDefectiveProducts(new BigDecimal(def));
                                record.setPercentage(new BigDecimal(i2).setScale(BigDecimal.ROUND_DOWN,2).toString());
                                mark = false;
                            }
                        }
                    }

                    record.setPercentage(sysConfig.getConfValueMb());

//                    BigDecimal add = record.getNonDefective().add(record.getDefectiveProducts()).add(record.getPending());
//                    record.setInvest(add);
                }
            }
        }
        return list;
    }

    @Override
    public IPage<QualityData> qualityDataNextApi(Integer page, Integer limit, String cusCode, String startTime, String endTime, String material) {
        //获取基础数据
        IPage<QualityData> list = getDataApi(page, limit, cusCode, startTime, endTime, material);

        //查询本地流转卡数据
        for (CustomQualityData customQualityData : customQualityDataService.qualityDataList(startTime, endTime)) {
            for (DepConstant value : DepConstant.values()) {
                if (customQualityData.getMaterial().contains(value.getCode())){
                    customQualityData.setStrDepartmentName(value.getMessage());
                }
            }
            QualityData bean = BeanUtil.toBean(customQualityData, QualityData.class);
            list.getRecords().add(bean);
        }

        for (QualityData record : list.getRecords()) {
            if(StringUtils.isNotEmpty(record.getStrDepartmentName())){
                record.setStrDepartmentName(record.getStrDepartmentName().replace("课",""));
            }
        }

        //获取配置中的 良率标准
        List<SysConfig> configs = sysConfigMapper.selectList(Wrappers.lambdaQuery(SysConfig.class));
        if (!configs.isEmpty()){
            //根据 科目名称 和 类别分组
            Map<String, List<SysConfig>> collect = configs.stream().collect(Collectors.groupingBy(obj-> obj.getDepName()+"-"+obj.getPartsType()));
            for (QualityData record : list.getRecords()) {
                //拼接 key
                String key = null;
                for (ConfigConstant value : ConfigConstant.values()) {
                    if (record.getStrGoodsName().contains(value.getCode())){
                        key = record.getStrDepartmentName() +"-"+ value.getMessage();
                    }
                }
                List<SysConfig> confs = collect.get(key);
                if(null != confs && !confs.isEmpty()){
                    SysConfig sysConfig = confs.get(0);
                    //良率
                    double per = Double.parseDouble(record.getPercentage());
                    //下限
                    double con = Double.parseDouble(sysConfig.getConfValue());
                    //如果小于最低标准 ，降低不良品 提升良率
                    if (per < con){
                        //循环 -1 一直到最低标准
                        int def = record.getDefectiveProducts().intValue();
                        int non = record.getNonDefective().intValue();
                        for (int i = 1; i <= def ; i++) {
                            double i2 = (double) non / (non + (def - i)) * 100;
                            // 大于良率
                            if (i2 >= con){
                                //把不良品数减下去的加到 投入数 上面
                                record.setInvest(record.getInvest().add(BigDecimal.valueOf(i)));
                                record.setDefectiveProducts(new BigDecimal(def - i));
                                record.setPercentage(new BigDecimal(i2).setScale(BigDecimal.ROUND_DOWN,2).toString());
                                break;
                            }
                        }
                    }

                    //上限
                    double conMax = Double.parseDouble(sysConfig.getConfValueMax());
                    if (per > conMax){
                        int def = record.getDefectiveProducts().intValue();
                        int non = record.getNonDefective().intValue();
                        boolean mark = true;
                        while (mark){
                            ++def;
                            //增加不良品降低良品
                            double i2 = (double) non / (non + def) * 100;
                            // 大于良率
                            if (i2 <= conMax){
                                //把不良品数减下去的加到 投入数 上面
                                record.setInvest(record.getInvest().add(BigDecimal.valueOf(def)));
                                record.setDefectiveProducts(new BigDecimal(def));
                                record.setPercentage(new BigDecimal(i2).setScale(BigDecimal.ROUND_DOWN,2).toString());
                                mark = false;
                            }
                        }
                    }

                    record.setPercentage(sysConfig.getConfValueMb());

//                    BigDecimal add = record.getNonDefective().add(record.getDefectiveProducts()).add(record.getPending());
//                    record.setInvest(add);
                }
            }
        }
        return list;
    }

    public IPage<QualityData> getDataApi(Integer page, Integer limit, String cusCode, String startTime, String endTime, String material){
        //获取供应商
        List<String> set = new ArrayList<>();

        // 根据开始日期展示 料号
        List<InitialStock> initialStocks = initialStockService.list(Wrappers.lambdaQuery(InitialStock.class)
                .gt(InitialStock::getUpdateTime, startTime + " 00:00:00").like(StringUtils.isNotEmpty(material),InitialStock::getDjMaterial,material));
        initialStocks.stream().map(InitialStock::getDjMaterial).forEach(set::add);

        //获取本地设定的料号
        List<BaseMaterial> materials = baseMaterialService.list(Wrappers.lambdaQuery(BaseMaterial.class)
                .eq(BaseMaterial::getCusCode, cusCode).eq(BaseMaterial::isChecked,true).ne(BaseMaterial::getClassType, "B")
                .like(StringUtils.isNotEmpty(material),BaseMaterial::getDjMaterial,material)
        );
        if (null != materials){
            set.addAll(materials.stream().map(BaseMaterial::getDjMaterial).collect(Collectors.toList()));
        }

        IPage<QualityData> list = selectPageList(page, limit, startTime, endTime, set);
        if (!list.getRecords().isEmpty()){
            Map<String, List<BaseMaterial>> listMap = materials.stream().collect(Collectors.groupingBy(BaseMaterial::getDjMaterial));
            for (QualityData record : list.getRecords()) {
                //不是委外数据
                if (StringUtils.isEmpty(record.getTypeName())){
                    //计算待处理
                    BigDecimal invest = record.getInvest();
                    invest = invest.subtract(record.getNonDefective()).subtract(record.getDefectiveProducts());
                    record.setPending(invest);
                    record.setPendingCumulative(invest);
                    if (invest.intValue() < 1){
                        record.setPending(BigDecimal.valueOf(0));
                        record.setPendingCumulative(BigDecimal.valueOf(0));
                    }
                    List<BaseMaterial> materialList = listMap.get(record.getMaterial());
                    if (null != materialList){
                        if (!materialList.isEmpty()){
                            BaseMaterial baseMaterial = materialList.get(0);
                            if (baseMaterial.getClassType().equals("A")){
                                record.setStrDepartmentName(record.getCusMaterial());
                            }
                        }
                    }
                }else {
                    //是委外数据
                    record.setInvest(record.getNonDefective());
                    record.setPlanSum(record.getNonDefective());
                    record.setPending(BigDecimal.valueOf(0));
                    record.setPendingCumulative(BigDecimal.valueOf(0));
                    record.setStrDepartmentName(DepConstant.getMessage(record.getMaterial()));
                }
            }
        }
        return list;
    }
}
